Skip to content

Conversation

caioessouza
Copy link
Contributor

@caioessouza caioessouza commented May 9, 2025

Pull request type

  • Code changes (bugfix, features)

Checklist

  • Lint (black rocketpy/ tests/) has passed locally
  • All tests (pytest tests -m slow --runslow) have passed locally
  • CHANGELOG.md has been updated (if relevant)

Current behavior

Rocketpy SolidMotor class simulates the grain regression either radially and axially by default.

This PR is related to the following issue:
ENH: Enable only radial burning #801

New behavior

Now it's possible to the user to change from the default behavior to a only radial regression by setting the new "only_radial_burning" optional parameter as True in the SolidMotor class.

Breaking change

  • No

Additional information

Here is an example of the comparison between the default burning and the only radial one applied to the getting_started.ipynb simulation. The pytest tests haven't passed locally because of a windows problem.

GRAFICO1NOVO
GRAFICO2NOVO
GRAFICO3NOVO

only_radial_burn optional parameter added and used in the functions related to the grain regression as a conditon to change the applied equations.

Still need to update the comment section, the CHANGELOG and maybe the dict related functions, but not sure about the last one yet.
The new parameter of the SolidMotor class was removed from super, since it's not on the Motor class. The dict functions were updated to take this new parameter into acount. Also the comments about the SolidMotor class parameters were updated.

Still need to do some tests running the code to be sure everything is ok, then I can open the PR.
Corrected some minor code erros, like calling evaluate geometry before defining self.only_radial_burn. Also had to change the grain_height_derivative to zero in the case of only radial burn, it was leading to some physical incoherences, because the grain was still burning axially. The last tests to evaluate the physical behaviour went pretty well, so I'll open the PR.
@caioessouza caioessouza requested a review from a team as a code owner May 9, 2025 23:40
Copy link

codecov bot commented May 16, 2025

Codecov Report

Attention: Patch coverage is 29.16667% with 17 lines in your changes missing coverage. Please review.

Project coverage is 80.08%. Comparing base (4df0b38) to head (95970b9).
Report is 20 commits behind head on develop.

Files with missing lines Patch % Lines
rocketpy/motors/solid_motor.py 29.16% 17 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop     #815      +/-   ##
===========================================
+ Coverage    79.11%   80.08%   +0.96%     
===========================================
  Files           96       98       +2     
  Lines        11575    12042     +467     
===========================================
+ Hits          9158     9644     +486     
+ Misses        2417     2398      -19     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Member

@MateusStano MateusStano left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we missing something in the HybridMotor class here? If we want to define a a HybridMotor with only radial burning garin how would we do that currently?

@Gui-FernandesBR
Copy link
Member

Are we missing something in the HybridMotor class here? If we want to define a a HybridMotor with only radial burning garin how would we do that currently?

I recommend modifyng the hybrid class in another PR, it's easier to reivew it.

Copy link
Member

@Gui-FernandesBR Gui-FernandesBR left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great PR.

I recommend keeping this PR to solidmotor (possibly renaming it).
Later you could extend the feature to also cover hybrid motors.

Also, I believe two other steps are important:

  1. Update the Motor page on our documentation to include this new feature
  2. Include new tests!!

@Gui-FernandesBR
Copy link
Member

But if you really want to include hybrid motors here, not a problem

@Gui-FernandesBR Gui-FernandesBR linked an issue May 16, 2025 that may be closed by this pull request
@Gui-FernandesBR Gui-FernandesBR requested a review from Copilot May 16, 2025 21:05
Copilot

This comment was marked as outdated.

The "only_radial_burning" parameter was added and set as default on the hybrid class. Also, the description of the new parameter was updated and 2 coments about derivatives set to zero were added.
only_radial_burn argument order corrected
The solid motor integrations test was created and the solid and hybrid motors unit tests were modified to add checks to the new only_radial_burning class and parameters. Also a correction was made in the hybrid unit tests to fix the test time.
Copy link
Member

@Gui-FernandesBR Gui-FernandesBR left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code looks better now, I think it is just a matter of taking a deeper look into the calculations and checking that everything is correct.

Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR enables users to restrict solid motor grain burning to only the radial direction by introducing a new only_radial_burn parameter. This enhancement allows for more accurate simulation of axially inhibited grains or hybrid motors where axial burning is not desired.

  • Added only_radial_burn boolean parameter to both SolidMotor and HybridMotor classes with appropriate default values
  • Modified geometry evaluation logic to conditionally disable axial burning based on the new parameter
  • Implemented comprehensive test coverage for the new functionality

Reviewed Changes

Copilot reviewed 6 out of 7 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
rocketpy/motors/solid_motor.py Adds only_radial_burn parameter and implements conditional burning logic in geometry calculations
rocketpy/motors/hybrid_motor.py Propagates only_radial_burn parameter to HybridMotor with default value of True
tests/unit/test_solidmotor.py Adds unit tests for radial burn parameter effects and geometry evaluation
tests/unit/test_hybridmotor.py Updates test time ranges and adds comprehensive tests for hybrid motor radial burn behavior
tests/integration/test_solidmotor.py Adds new integration test file for SolidMotor info methods
CHANGELOG.md Documents the new feature addition

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

caioessouza and others added 2 commits August 14, 2025 12:57
Comments checked and resolved.
@Gui-FernandesBR please check the CHANGELOG.md to see if it's correct now.
caioessouza and others added 10 commits October 2, 2025 15:44
All tests approved locally.
The spherical_oxidizer_tank fixture was a problem, so I changed the hybrid tank to the oxidizer_tank fixture instead. It's important to fix the spherical_oxidizer_tank fixture.
Unit tests corrected.
mock_show removed from the integration test
mock_show returned to unit/test_solidmotor.py
# pylint: disable=unused-argument comment added to fix the tests
Comment on lines +34 to +36
- ENH: Enable only radial burning [#815](https://github.com/RocketPy-Team/RocketPy/pull/815)
- ENH: Controller (AirBrakes) and Sensors Encoding [#849] (https://github.com/RocketPy-Team/RocketPy/pull/849)
- EHN: Addition of ensemble variable to ECMWF dictionaries [#842] (https://github.com/RocketPy-Team/RocketPy/pull/842)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are duplicates here. Try to get the develop CHANGELOG and only add your PR to the top.

interpolation_method="linear",
coordinate_system_orientation="nozzle_to_combustion_chamber",
reference_pressure=None,
only_radial_burn=True,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There can be made some discussion here on the severity of it, but this is likely a breaking change: the default of this attribute should be False, otherwise all the current code with hybrid motors would have its behavior changed. Do you agree @Gui-FernandesBR ?

interpolation_method="linear",
coordinate_system_orientation="nozzle_to_combustion_chamber",
reference_pressure=None,
only_radial_burn=True,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This parameter needs to be documented in the class and __init__ docstrings.


@pytest.fixture
def hybrid_motor(spherical_oxidizer_tank):
def hybrid_motor(oxidizer_tank):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't oppose to it if needed, but any particular reason for changing the fixture name?

Comment on lines +284 to +321
def test_only_radial_burn_parameter_effect(cesaroni_m1670):
# Tests if the only_radial_burn flag is properly set
motor = cesaroni_m1670
motor.only_radial_burn = True
assert motor.only_radial_burn is True

# When only_radial_burn is active, burn_area should consider only radial area
burn_area_radial = (
2
* np.pi
* (motor.grain_inner_radius(0) * motor.grain_height(0))
* motor.grain_number
)
assert np.isclose(motor.burn_area(0), burn_area_radial, atol=1e-12)


def test_evaluate_geometry_updates_properties(cesaroni_m1670):
# Checks if after instantiation, grain_inner_radius and grain_height are valid functions
motor = cesaroni_m1670

assert hasattr(motor, "grain_inner_radius")
assert hasattr(motor, "grain_height")

# Checks if the domain of grain_inner_radius function is consistent
times = motor.grain_inner_radius.x_array
values = motor.grain_inner_radius.y_array

assert times[0] == 0 # expected initial time
assert (
values[0] == motor.grain_initial_inner_radius
) # expected initial inner radius
assert (
values[-1] <= motor.grain_outer_radius
) # final inner radius should be less or equal than outer radius

# Evaluates without error
val = motor.grain_inner_radius(0.5) # evaluate at intermediate time
assert isinstance(val, float)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly to the other tests, docstrings are needed to describe it and its fixture parameters.

Comment on lines +189 to +190
motor.solid.only_radial_burn = True
assert motor.solid.only_radial_burn is True
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is quite dangerous. I did not test nor exhaustively review the code, but here are some of my comments that I believe are relevant (feel free to correct me on that) if you want to support setting (post instantiation) this attribute:

  • The SolidMotor.evaluate_geometry method also sets some of the instance attributes, such as self.grain_burn_out and self.grain_inner_radius;
  • Simply toggling the attribute only_radial_burn would not change the values of those attributes, therefore their old values would be kept.

On the top of my head, I see two possible solutions here:

  1. Supporting this toggling after instantiation in which other values of the class should be adapted is the task of a setter:
class SolidMotor(Motor):
    def __init__(self, ..., only_radial_burn=False):
        ...
        self._only_radial_burn = only_radial_burn

    @property
    def only_radial_burn(self):
        return self._only_radial_burn

    @only_radial_burn.setter
    def only_radial_burn(self, value):
        self._only_radial_burn = value
        self.evaluate_geometry()

class HybridMotor(Motor):
    def __init__(self, ..., only_radial_burn=False):
        ...
        self._only_radial_burn = only_radial_burn

    @property
    def only_radial_burn(self):
        return self._only_radial_burn

    @only_radial_burn.setter
    def only_radial_burn(self, value):
        self.solid.only_radial_burn = value
        reset_funcified_method(self)
  1. Alternative simpler solution: another possibility is to disallow the toggling of this attribute after instantiation. This is possible by using a property with no setter. In this way, the radial burn can only be selected on instantiation.
class SolidMotor(Motor):
    def __init__(self, ..., only_radial_burn=False):
        ...
        self._only_radial_burn = only_radial_burn

    @property
    def only_radial_burn(self):
        return self._only_radial_burn

@caioessouza could you confirm this is the case, i.e., toggling this attribute would cause the defined attributes from evaluate_geometry incorrectly keep their old values? If I understood things correctly, the tests for this new parameter did not catch that, which means they have room for improvement.

I, personally, have a slight preference for option 2, since it avoids complicating more this already delicate interaction between the motor types. Do you have any suggestions @MateusStano or @Gui-FernandesBR ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the best option is to make only_radial_burn not mutable.

This would make life much easier.

If you want to modify the value of only_radial_burn after instanciating the object, you should instantiate another object

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Backlog
Development

Successfully merging this pull request may close these issues.

ENH: Enable only radial burning
4 participants